/*
 * Copyright 2008-2009 Daniel Cachapa <cachapa@gmail.com>
 * 
 * This program is distributed under the terms of the GNU General Public Licence Version 3
 * The licence can be read in its entirety in the LICENSE.txt file accompaning this source code,
 * or at: http://www.gnu.org/copyleft/gpl.html
 * 
 * This file is part of WeightWatch.
 *
 * WeightWatch is free software: you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation, version 3 of the License.
 *
 * WeightWatch is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with the WeightWatch source code. If not, see
 * <http://www.gnu.org/licenses/>.
 */

package net.cachapa.weightwatch;

import net.cachapa.weightwatch.util.MyDate;
import com.sun.lwuit.Image;
import java.util.Vector;
import net.cachapa.weightwatch.util.Chart;

public class WeightWatch {
	private Database db;
	private Preferences prefs;
	
	public WeightWatch() {
		db = new Database();
		prefs = new Preferences();
	}

	public boolean addValue(long time, double weight) {
		MyDate date = new MyDate(time);
		Value value = new Value(date, weight);
		
		Value prevValue = db.getValueBefore(date);
		if (prevValue == null) {
			value.trend = weight;
		} else {
			value.trend = Trend.getTrend(prevValue, value);
		}
		
		boolean result = db.addValue(value);
		if (db.getLatestValue() != value) {
			regenerateTrendValuesAfter(date);
		}
		return result;
	}

	public Vector getFullDatabase() {
		return db.getValues();
	}

	public Preferences getPreferences() {
		return prefs;
	}

	public void regenerateTrendValues() {
		Vector values = db.getValues();
		int size = values.size();
		Value value, prevValue = null;
		for (int i = 0; i < size; i++) {
			value = (Value)values.elementAt(i);
			value.trend = Trend.getTrend(prevValue, value);
			db.updateValue(value);
			prevValue = value;
		}
	}
	
	public void regenerateTrendValuesAfter(MyDate date) {
		Vector values = db.getValues();
		int size = values.size();
		Value value, prevValue = null;
		for (int i = 0; i < size; i++) {
			value = (Value)values.elementAt(i);
			if (!value.date.isBefore(date)) {
				value.trend = Trend.getTrend(prevValue, value);
				db.updateValue(value);
			}
			prevValue = value;
		}
	}
		
	public Plan getPlan() {
		return prefs.getPlan();
	}
	
	public Database getDatabase() {
		return db;
	}
	
	public double getCurrentBmi() {
		double userHeight = prefs.getUserHeight();
		double bmi;
		Value value = db.getLatestValue();
		if (userHeight != 0 && value.trend != 0) {
			bmi = Bmi.calculateBMI(value.trend, userHeight, prefs.isMetricUnits());
			bmi = (double) (int)(bmi*10) / 10;
		} else {
			bmi = 0;
		}
		return bmi;
	}
	
	public Image drawMonthChart(MyDate date, int width, int height) {
		Vector values = db.getMonth(date.getMonth(), date.getYear());
		MyDate startDate = new MyDate(1, date.getMonth(), date.getYear());
		MyDate endDate = new MyDate(MyDate.getDaysInMonth(date.getMonth(), date.getYear()), date.getMonth(), date.getYear());
		return Chart.generateChart(width, height, values, prefs, startDate, endDate);
	}
	
	public Image drawYearChart(MyDate date, int width, int height) {
		Vector values = db.getYear(date.getYear());
		MyDate startDate = new MyDate(1, 1, date.getYear());
		MyDate endDate = new MyDate(31, 12, date.getYear());
		return Chart.generateChart(width, height, values, prefs, startDate, endDate);
	}
	
	public Image drawCompleteChart(int width, int height) {
		Vector values = db.getValues();
		MyDate startDate = ((Value)values.firstElement()).date;
		MyDate endDate = ((Value)values.lastElement()).date;
		return Chart.generateChart(width, height, values, prefs, startDate, endDate);
	}
	
	public void deleteValue(Value value) {
		db.deleteValue(value);
		regenerateTrendValuesAfter(value.date);
	}
	
	public void deleteDatabase() {
		db.deleteDatabase();
	}
	
//	public void saveImage(String path) {
//		byte[] pngData = Encoder.toPNG(cachedImage);
//		FileConnection file = null;
//		OutputStream os = null;
//		try {
//			file = (FileConnection) Connector.open("file:///" + path, Connector.WRITE);
//			if (!file.exists())
//				file.create();
//			else
//				file.truncate(0);
//			os = file.openOutputStream();
//			os.write(pngData);
//			os.flush();
//		} catch (IOException ex) {
//			ex.printStackTrace();
//		} finally {
//			try {
//                if (os != null)
//                    os.close();
//                if (file != null)
//                    file.close();
//            } catch (Exception ex) {
//                ex.printStackTrace();
//            }
//		}
//	}
}